#include "TrSession.h"
#include "LogManager.h"
#include <QCoreApplication>
#include <QDateTime>
#include <iostream>
#include <iomanip>

using namespace Market;

void printTimePoints(const QVector<QString>& timePoints, const std::string& periodName) {
    std::cout << "\nTime points for " << periodName << ":" << std::endl;
    std::cout << std::string(40, '-') << std::endl;
    for (const auto& time : timePoints) {
        std::cout << time.toStdString() << std::endl;
    }
}

void testTradingTime(const QString& sessionName) {
    std::cout << "\nTesting trading time for " << sessionName.toStdString() << ":" << std::endl;
    std::cout << std::string(80, '-') << std::endl;

    const std::vector<std::pair<QTime, std::string>> testTimes = {
        {QTime(8, 59), "开盘前"},
        {QTime(9, 0), "开盘时"},
        {QTime(10, 14), "上午交易"},
        {QTime(10, 15), "上午休息开始"},
        {QTime(10, 30), "上午休息结束"},
        {QTime(11, 30), "午休开始"},
        {QTime(13, 30), "午休结束"},
        {QTime(15, 0), "收盘"},
        {QTime(20, 59), "夜盘前"},
        {QTime(21, 0), "夜盘开始"},
        {QTime(23, 0), "夜盘结束"},
        {QTime(0, 0), "午夜"},
        {QTime(2, 30), "凌晨"}
    };

    auto session = SESSION;
    for (const auto& [time, desc] : testTimes) {
        bool isTrading = session->isInTradingTime(sessionName, time);
        std::cout << std::left 
                  << std::setw(15) << time.toString("HH:mm").toStdString()
                  << std::setw(20) << desc
                  << (isTrading ? "交易中" : "非交易")
                  << std::endl;
    }
}

void testBarTimes(const QString& sessionName, TrPeriod period) {
    std::cout << "\nTesting bar times for " << sessionName.toStdString() 
              << " period " << static_cast<int>(period) << ":" << std::endl;
    std::cout << std::string(80, '-') << std::endl;

    const std::vector<QDateTime> testTimes = {
        QDateTime(QDate::currentDate(), QTime(9, 5)),
        QDateTime(QDate::currentDate(), QTime(10, 14)),
        QDateTime(QDate::currentDate(), QTime(10, 31)),
        QDateTime(QDate::currentDate(), QTime(13, 35)),
        QDateTime(QDate::currentDate(), QTime(21, 5)),
        QDateTime(QDate::currentDate(), QTime(22, 59))
    };

    auto session = SESSION;
    for (const auto& time : testTimes) {
        auto barStart = session->getBarStartTime(sessionName, period, time);
        auto nextBar = session->getNextBarTime(sessionName, period, time);
        
        std::cout << std::left 
                  << std::setw(15) << time.toString("HH:mm").toStdString()
                  << std::setw(20) << (barStart.isValid() ? barStart.toString("HH:mm").toStdString() : "无效")
                  << (nextBar.isValid() ? nextBar.toString("HH:mm").toStdString() : "无效")
                  << std::endl;
    }
}

void testSession(const std::string& sessionId) {
    QString qSessionId = QString::fromStdString(sessionId);
    
    // 测试交易时间
    testTradingTime(qSessionId);
    
    // 测试不同周期的Bar时间
    const std::vector<TrPeriod> periods = {
        TrPeriod::M1, TrPeriod::M5, TrPeriod::M10, TrPeriod::M15, 
        TrPeriod::M30, TrPeriod::H1, TrPeriod::H2
    };
    
    for (auto period : periods) {
        testBarTimes(qSessionId, period);
    }

    // 测试时间点列表
    const std::vector<std::pair<TrPeriod, std::string>> periodNames = {
        {TrPeriod::M1, "1分钟"},
        {TrPeriod::M3, "3分钟"},
        {TrPeriod::M5, "5分钟"},
        {TrPeriod::M10, "10分钟"},
        {TrPeriod::M15, "15分钟"},
        {TrPeriod::M30, "30分钟"},
        {TrPeriod::H1, "1小时"},
        {TrPeriod::H2, "2小时"}
    };

    for (const auto& [period, name] : periodNames) {
        auto timePoints = TrSession::Get(qSessionId, period);
        printTimePoints(timePoints, name);
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    // 初始化日志
    Common::LogManager::instance()->init("../Config/tts24/logger.json");

    // 测试不同的交易时间模板
    const std::vector<std::pair<std::string, std::string>> sessions = {
        {"FN2300", "夜盘23:00收盘品种"}
    };

    for (const auto& [session, desc] : sessions) {
        std::cout << "\n\nTesting " << desc << " (" << session << ")" << std::endl;
        std::cout << std::string(100, '=') << std::endl;
        testSession(session);
    }

    return 0;
} 